#include "interface_switch.h"
#include "usrt_rev.h"
#include "ui_mainwindow.h"
#include "mainwindow.h"
#include <QString>
#include <QRegularExpression>
Test_item T_item = Item_None;
static Item_5_data_info Item_5_data;
static Item_67_data_info Item_67_data;
static Item_89_data_info Item_89_data;
static Item_89_data_info Item_10_data[5];
static Item_12_data_info Item_12_data;
void Item_5_data_info_init(void)
{
    Item_5_data.NG_num = 0;
    Item_5_data.SU_num = 0;
    Item_5_data.SCAN_num = 0;
    Item_5_data.Common_Cali_Value = 0;
    Item_5_data.ibeacon_Cali_Value = 0;
}

void Item_67_data_info_init(void)
{
    Item_67_data.request_num = 0;
    Item_67_data.connect_num = 0;
    Item_67_data.disconnect_num = 0;
    Item_67_data.fault_num = 0;
    Item_67_data.rece_connect_flag = 0;
}

void Item_89_data_info_init(void)
{
    Item_89_data.connect_timer = 0;
    Item_89_data.disconnect_num = 0;
}

void Item_10_data_info_init(void)
{
    uint8_t i = 0;
    for (i = 0; i < 5; i++)
    {
        Item_10_data[i].connect_timer = 0;
        Item_10_data[i].disconnect_num = 0;
    }
}

void Item_12_data_info_init(void)
{
    Item_12_data.SRF_Success = 0;
    Item_12_data.SRF_fail = 0;
    Item_12_data.SRR_Success = 0;
    Item_12_data.SRR_fail = 0;
    Item_12_data.SRF_Cali_Value = 0;
    Item_12_data.SRR_Cali_Value = 0;
}

void Item_67_fault_time_fun(void)
{
    /*30s内如果没收到连接成功，则记录故障*/
    if (0 == Item_67_data.rece_connect_flag)
    {
        Item_67_data.fault_num += 1;
        set_ui_QTable_content(1, 3, QString::number(Item_67_data.fault_num));
    }else{
        Item_67_data.rece_connect_flag = 0;
    }
}
void Item_5_QTime_max_init(void)
{
    set_timer_outflag(0); // 设置超时标志
}

void Item_67_QTime_max_init(void)
{
    set_timer_outflag(0); // 设置超时标志
}

void Item_89_QTime_max_init(void)
{
    set_timer_outflag(0); // 设置超时标志
}

void Item_10_QTime_max_init(void)
{
    set_timer_outflag(0); // 设置超时标志
}

void Item_12_QTime_max_init(void)
{
    set_timer_outflag(0); // 设置超时标志
}

/**
 * 清除UART状态信息
 * 此函数用于重置UART通信的状态计时器，并检查是否需要更新UI中的状态显示
 */
void clean_uart_sta(void)
{
    switch (T_item)
    {
    case Item_None:
        // 如果T_item是Item_None，则不执行任何操作
        break;
    case Item_5:
        time_ruart_status_start_stop(1, 5 * 1000);
        if (1 == rt_timer_outflag())
        {
            //qDebug() << "Item_5——clean_uart_sta";
            Item_5_QTime_max_init();
            set_ui_QTable_content(1, 3, "正常");
        }
        break;
    case Item_6:
    case Item_7:
        time_ruart_status_start_stop(1, 60 * 1000);
        if (1 == rt_timer_outflag())
        {
            Item_67_QTime_max_init();
            set_ui_QTable_content(1, 4, "正常");
        }
        break;
    case Item_8:
    case Item_9:
        time_ruart_status_start_stop(1, 120 * 1000);
        if (1 == rt_timer_outflag())
        {
            Item_89_QTime_max_init();
            set_ui_QTable_content(1, 3, "正常");
        }
        break;
    case Item_10:
        time_ruart_status_start_stop(1, 120 * 1000);
        if (1 == rt_timer_outflag())
        {
            Item_10_QTime_max_init();
            set_ui_QTable_content(3, 0, "正常");
        }
        break;
    case Item_12:
        time_ruart_status_start_stop(1, 5 * 1000);
        if (1 == rt_timer_outflag())
        {
            Item_12_QTime_max_init();
            set_ui_QTable_content(1, 5, "正常");
        }
        break;
    default:
        break;
    }
}

void get_QTable_value(void)
{
    switch (T_item)
    {
    case Item_5:
        Item_5_data.Common_Cali_Value = rt_QTable_value(1,4);
        Item_5_data.ibeacon_Cali_Value = rt_QTable_value(1,5);
        break;
    case Item_12:
        /* code */
        Item_12_data.SRF_Cali_Value = rt_QTable_value(1,6);
        Item_12_data.SRR_Cali_Value = rt_QTable_value(1,7);
        break;
    default:
        break;
    }
}


/*
Step1：BTA_SRF上电后处于广播模式（产品代码）
Step2：BTA_SRR上电后处于扫描模式（扫描间隔1s，扫描窗口1s，持续扫描）
Step3：BTA_SRR每秒将扫描的结果通过Uart发送给电脑（common_adv: xx数量, ibeacon_adv: xx，每秒清零重新计数）通过识别关键字符串进行数据判定
Step4：上位机获取并保存Uart报文（时间戳+报文），若一秒钟未扫描到（或小于xx（需标测）次，实际联调时可测试下）普通广播或ibeacon广播，记录故障。
 */
void Item_5_data_handle(QByteArray buffer)
{
    // 初始化一个空字符串，用于存储转换后的数据
    bool OK = true;
    QString string = "";
    uint16_t common_adv = 0;
    uint16_t ibeacon_adv = 0;

    string += QObject::tr(buffer);
    QRegularExpression regex;
    regex.setPattern(R"(common_adv: (\d+), ibeacon_adv: (\d+))");
    QRegularExpressionMatch match = regex.match(string);
    if(match.hasMatch())
    {
        QString common_adv_count = match.captured(1);
        QString ibeacon_adv_count = match.captured(2);
        common_adv = static_cast<uint16_t>(common_adv_count.toUShort(&OK));
        ibeacon_adv = static_cast<uint16_t>(ibeacon_adv_count.toUShort(&OK));
    }else{
        OK = false;
    }

    if ((false == OK))
    {
        return;
    }
    clean_uart_sta();

    if (common_adv > Item_5_data.Common_Cali_Value && ibeacon_adv > Item_5_data.ibeacon_Cali_Value)
    {
        /*记录成功次数+1*/
        Item_5_data.SU_num += 1;
    }
    else
    {
        /*记录NG次数+1*/
        Item_5_data.NG_num += 1;
    }
    /*扫描次数*/
    Item_5_data.SCAN_num += 1;

    set_ui_QTable_content(1, 0, QString::number(Item_5_data.SCAN_num));
    set_ui_QTable_content(1, 1, QString::number(Item_5_data.SU_num));
    set_ui_QTable_content(1, 2, QString::number(Item_5_data.NG_num));
}

/*
Step1：BTA_SRF上电后处于扫描模式（产品代码）
Step2：Keyfob处于广播模式（产品代码）
Step3：BTA_SRF主动发起连接请求和断开（连接保持15秒后自动断开，断开15秒后再次发起连接请求，循环这个过程）
Step4：BTA_SRF将蓝牙连接请求，蓝牙已连接，蓝牙已断开的记录通过Uart发送给上位机（step1：ble request/  step2：ble connect,/ step3：ble disconnect）（异步信号）
Step5：上位机获取并保存Uart报文（时间戳+报文），若30秒内未有蓝牙连接成功事件，记录故障。
*/
void Item_67_data_handle(QByteArray buffer)
{
    // 初始化一个空字符串，用于存储转换后的数据
    QString string = "";
    // 将缓冲区中的数据转换为字符串并追加到之前的字符串中
    // 数据是一行一行传送的，要保存所有数据
    string += QObject::tr(buffer);

    if (0 == QString::localeAwareCompare(string, "ble request\n"))
    {
        Item_67_data.request_num += 1;
        /*收到ble request开启定时器*/
        time_67_fault_start_stop(1,30*1000);
    }
    else if (0 == QString::localeAwareCompare(string, "ble connect\n"))
    {
        /* code */
        Item_67_data.connect_num += 1;
        Item_67_data.rece_connect_flag = 1;
    }
    else if (0 == QString::localeAwareCompare(string, "ble disconnect\n"))
    {
        /* code */
        Item_67_data.disconnect_num += 1;
    }
    else
    {
        return;
    }
    clean_uart_sta();
    set_ui_QTable_content(1, 0, QString::number(Item_67_data.request_num));
    set_ui_QTable_content(1, 1, QString::number(Item_67_data.connect_num));
    set_ui_QTable_content(1, 2, QString::number(Item_67_data.disconnect_num));
}

/**
 * 处理Item 89的数据
 * 该函数解析给定的QByteArray缓冲区中的数据，提取BLE连接状态和断开连接次数，并更新UI显示
 * @param buffer 包含BLE状态信息的字节缓冲区
 */
void Item_89_data_handle(QByteArray buffer)
{
    // 初始化操作状态变量
    bool OK = true;
    // 初始化字符串变量，用于存储解析后的数据
    QString string = "";
    // 初始化BLE状态变量
    QString ble_status;
    // 初始化断开连接次数变量
    uint32_t disconnect_count = 0;
    
    // 将缓冲区数据转换为字符串并添加到string变量中
    string += QObject::tr(buffer);
    
    // 定义正则表达式，用于匹配BLE状态信息
    QRegularExpression re("ble_status:\\s*(connect|disconnect),\\s*disconnect \\s*num:(\\d+)");
    // 使用正则表达式匹配字符串中的BLE状态信息
    QRegularExpressionMatch match = re.match(string);
    
    // 检查是否找到匹配项
    if (match.hasMatch())
    {
        // 提取匹配项中的BLE状态和断开连接次数
        ble_status = match.captured(1);
        disconnect_count = static_cast<uint32_t>(match.captured(2).toUShort(&OK));
    }else{
        // 如果没有找到匹配项，则退出函数
        return;
    }
    
    // 清除UART状态，准备更新UI
    clean_uart_sta();
    
    // 根据BLE状态更新UI显示
    if(0 == QString::localeAwareCompare(ble_status, "connect"))
    {
        // 如果BLE状态为连接，则增加连接计数器并更新UI
        Item_89_data.connect_timer += 1;
        set_ui_QTable_content(1, 1, QString::number(Item_89_data.connect_timer));
        // 更新断开连接次数并更新UI
        Item_89_data.disconnect_num += disconnect_count;
        set_ui_QTable_content(1, 2, QString::number(Item_89_data.disconnect_num));
    }else if(0 == QString::localeAwareCompare(ble_status, "disconnect")){
        // 如果BLE状态为断开连接，则增加断开连接次数并更新UI
        Item_89_data.disconnect_num += disconnect_count;
        set_ui_QTable_content(1, 2, QString::number(Item_89_data.disconnect_num));
    }
}

/*Step1：BTA_SRF上电后处于广播模式（产品代码，屏蔽认证）
Step2：#3、#4、#5、#6手机，处于扫描模式（Nrf Connect），#7 Keyfob处于广播模式 
Step3：#3、#4、#5、#6 Nrf Connect主动发起连接
Step4：BTA_SRF主动对#7 Keyfob发起连接
Step5：BTA_SRF每分钟获取蓝牙连接状态和断开次数并发送给上位机
（ #3-ble_status: connect/disconnect, disconnect num：xx
    #4-ble_status: connect/disconnect, disconnect num：xx
    #5-ble_status: connect/disconnect, disconnect num：xx
    #6-ble_status: connect/disconnect, disconnect num：xx
    #7-ble_status: connect/disconnect, disconnect num：xx）
Step5：上位机获取并保存Uart报文（时间戳+报文）
*/
void Item_10_data_handle(QByteArray buffer)
{
    // 初始化操作状态变量
    bool OK = true;
    // 初始化字符串变量，用于存储解析后的数据
    QString string = "";
    // 初始化BLE状态变量
    QString ble_status;
    // 初始化断开连接次数变量
    uint32_t disconnect_count = 0;
    uint8_t Serial_Num = 0;
    // 将缓冲区数据转换为字符串并添加到string变量中
    string += QObject::tr(buffer);

    // 定义正则表达式，用于匹配BLE状态信息
    QRegularExpression re("#(3|4|5|6|7)-ble_status:\\s*(connect|disconnect),\\s*disconnect \\s*num:(\\d+)");
    // 使用正则表达式匹配字符串中的BLE状态信息
    QRegularExpressionMatch match = re.match(string);
    // 检查是否找到匹配项
    if (match.hasMatch())
    {
        // 提取匹配项中的BLE状态和断开连接次数
        Serial_Num = static_cast<uint8_t>(match.captured(1).toUShort(&OK));
        ble_status = match.captured(2);
        disconnect_count = static_cast<uint32_t>(match.captured(3).toUShort(&OK));
    }else{
        // 如果没有找到匹配项，则退出函数
        return;
    }
    // 清除UART状态，准备更新UI
    clean_uart_sta();

    // 根据BLE状态更新UI显示
    if(0 == QString::localeAwareCompare(ble_status, "connect"))
    {
        // 如果BLE状态为连接，则增加连接计数器并更新UI
        Item_10_data[Serial_Num-3].connect_timer += 1;
        set_ui_QTable_content(1, Serial_Num-2, QString::number(Item_10_data[Serial_Num-3].connect_timer));
        // 更新断开连接次数并更新UI
        Item_10_data[Serial_Num-3].disconnect_num += disconnect_count;
        set_ui_QTable_content(3, Serial_Num-2, QString::number(Item_10_data[Serial_Num-3].disconnect_num));
    }else if(0 == QString::localeAwareCompare(ble_status, "disconnect")){
        // 如果BLE状态为断开连接，则增加断开连接次数并更新UI
        Item_10_data[Serial_Num-3].disconnect_num += disconnect_count;
        set_ui_QTable_content(3, Serial_Num-2, QString::number(Item_10_data[Serial_Num-3].disconnect_num));
    }
}


/*
Step1：BTA_SRF上电后处于广播模式（产品代码）
Step2：NIO Phone与BTA_SRF建立蓝牙连接并协商UWB测距会话
Step3：BTA_SRF将UWB测距配置通过CAN发送给BTA_SRR
Step4：BTA_SRF和BTA_SRR周期性的与NIO Phone进行UWB测距（周期由NIO Phone确定）
Step5：BTA_SRR将UWB测距结果通过CAN发送给BTA_SRF
Step6：BTA_SRF把BTA_SRF和BTA_SRR的UWB测距结果，每秒通过Uart 输出（BLE Status: Connect/Disconnect, SRF Success: xx, SRR Success: xx）；
下位机每秒数据清零重新累计，下位机需要自行判断测距的距离合理性输出成功次数；
上位机成功/失败次数每秒加1，成功/失败的判定（具体xx标定后上位机写入，xx＞上位机设定值，成功+1；xx<上位机设定值，失败+1）
 */
void Item_12_data_handle(QByteArray buffer)
{
    // 初始化操作状态变量
    bool OK = true;
    // 初始化BLE状态变量
    QString ble_status;
    uint32_t SRF_num = 0;
    uint32_t SRR_num = 0;
    // 初始化字符串变量，用于存储解析后的数据
    QString string = "";
    // 将缓冲区数据转换为字符串并添加到string变量中
    string += QObject::tr(buffer);
    // 定义正则表达式，用于匹配BLE状态信息
    QRegularExpression re("BLE Status:(Connect|Disconnect),SRF Success:(\\d+),SRR Success:(\\d+)\n");
    // 使用正则表达式匹配字符串中的BLE状态信息
    QRegularExpressionMatch match = re.match(string);
    // 检查是否找到匹配项
    if (match.hasMatch())
    {
        ble_status = match.captured(1);
        SRF_num = static_cast<uint32_t>(match.captured(2).toUShort(&OK));
        SRR_num = static_cast<uint32_t>(match.captured(3).toUShort(&OK));
    }else{
        // 如果没有找到匹配项，则退出函数
        return;
    }
    // 清除UART状态，准备更新UI
    clean_uart_sta();
    set_ui_QTable_content(1,4,ble_status);
    if (SRF_num > Item_12_data.SRF_Cali_Value)
    {
        Item_12_data.SRF_Success += 1;
        set_ui_QTable_content(1,0,QString::number(Item_12_data.SRF_Success));
    }else{
        Item_12_data.SRF_fail += 1;
        set_ui_QTable_content(1,1,QString::number(Item_12_data.SRF_fail));
    }
    if (SRR_num > Item_12_data.SRR_Cali_Value)
    {
        Item_12_data.SRR_Success += 1;
        set_ui_QTable_content(1,2,QString::number(Item_12_data.SRR_Success));
    }else{
        Item_12_data.SRR_fail += 1;
        set_ui_QTable_content(1,3,QString::number(Item_12_data.SRR_fail));
    }
    
    
}

/**
 * @brief 处理数据
 *
 * 根据当前项的类型处理接收到的数据缓冲区。该函数通过switch语句定向到特定的项处理函数，
 * 或者在项类型为Item_None或未定义的情况下不执行任何操作。
 *
 * @param buffer 包含待处理数据的字节数组
 */
void data_handle(QByteArray buffer)
{
    switch (T_item)
    {
    case Item_None:
        // 项类型为Item_None，不执行任何操作
        break;
    case Item_5:
        // 项类型为Item_5，调用专门的处理函数处理数据
        Item_5_data_handle(buffer);
        break;
    case Item_6:
    case Item_7:
        // 项类型为Item_5，调用专门的处理函数处理数据
        Item_67_data_handle(buffer);
        break;
    case Item_8:
    case Item_9:
        Item_89_data_handle(buffer);
        break;
    case Item_10:
        Item_10_data_handle(buffer);
        break;
    case Item_12:
        Item_12_data_handle(buffer);
        break;
    default:
        // 其他未定义的项类型，不执行任何操作
        break;
    }
}
